package com.yingxin.yxerp.module.attachment.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yingxin.yx.framework.commons.constant.PathConst;
import com.yingxin.yx.framework.commons.dto.AttachmentDto;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yx.framework.commons.helper.PropertiesHelper;
import com.yingxin.yx.framework.commons.id.IdHelper;
import com.yingxin.yxerp.module.attachment.entity.Attachment;
import com.yingxin.yxerp.module.attachment.mapper.AttachmentMapper;
import com.yingxin.yxerp.module.attachment.service.IAttachmentRelationService;
import com.yingxin.yxerp.module.attachment.service.IAttachmentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 附件表 服务实现类
 * @author zhuchangjie
 * @since 2022-01-23
 */

@Service
public class AttachmentServiceImpl
        extends ServiceImpl<AttachmentMapper, Attachment>
        implements IAttachmentService {

    @Autowired
    private IAttachmentRelationService attachmentRelationService;

    /**
     * 上传
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Attachment upload(MultipartFile file, String name, String bizId, String bizType, String bizAttr) {
        String uploadDir = PropertiesHelper.getInstance().getProperty(PathConst.UPLOAD_DIR);
        String filename;
        if (StringUtils.isNotBlank(name)) {
            filename = name;
        } else {
            filename = file.getOriginalFilename();
        }
        //日期路径
        String dirPath = getPath(uploadDir);
        // 随机文件名
        // String randomName = UUID.randomUUID().toString().replace("-", "");
        String randomName = IdHelper.snowflakeId();
        //后缀
        String ext = getFileExt(filename);
        // uri
        String path = dirPath + randomName;
        if (StringUtils.isNotBlank(ext)) {
            path = path + "." + ext;
        } else {
            String contentType = file.getContentType();
            if ("image/jpg".equals(contentType)) {
                path = path + ".jpg";
            } else if ("image/png".equals(contentType)) {
                path = path + ".png";
            }
        }
        try {
            file.transferTo(new File(uploadDir + path));
        } catch (IOException e) {
            e.printStackTrace();
            throw new BizException("附件上传异常");
        }
        Attachment attachment = new Attachment();
        attachment.setId(IdHelper.snowflakeId());
        attachment.setFileName(filename);
        attachment.setExt(ext);
        attachment.setPath(path.replaceAll("\\\\", "/"));
        attachment.setSize(file.getSize());
        save(attachment);
        if (StringUtils.isNotBlank(bizId)) {
            attachmentRelationService.create(attachment.getId(), bizId, bizType, bizAttr);
        }
        return attachment;
    }


    /**
     * 多个上传
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public List<Attachment> uploadBatch(List<MultipartFile> files, String bizId, String bizType, String bizAttr) {
        if (CollectionUtil.isEmpty(files)) {
            throw new BizException("附件为空");
        }
        List<Attachment> attachmentList = new ArrayList<>();
        for (MultipartFile file : files) {
            Attachment attachment = upload(file, null, bizId, bizType, bizAttr);
            attachmentList.add(attachment);
        }
        return attachmentList;
    }

    /**
     * get后缀
     */
    private String getFileExt(String originalFilename) {
        int idx = originalFilename.lastIndexOf(".");
        if (idx > 0 && idx != (originalFilename.length() - 1)) {
            return originalFilename.substring(idx + 1);
        }
        return "";
    }


    /**
     * getPath
     */
    private String getPath(String uploadDir) {
        Calendar calendar = Calendar.getInstance();
        //年
        int year = calendar.get(Calendar.YEAR);
        //月
        int month = calendar.get(Calendar.MONTH) + 1;
        //日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        String path = File.separator + "upload" + File.separator + year
                + File.separator + month + File.separator + day + File.separator;
        File file = new File(uploadDir + path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return path;
    }


    @Override
    public AttachmentDto getByBiz(String bizId, BusinessType bizType, String bizAttr) {
        return baseMapper.getByBiz(bizId, (bizType == null ? null : bizType.getType()), bizAttr);
    }

    @Override
    public List<AttachmentDto> listByBiz(String bizId, String bizType) {
        return baseMapper.listByBiz(bizId, bizType, null);
    }

    @Override
    public List<AttachmentDto> listByBiz(String bizId, BusinessType bizType) {
        return listByBiz(bizId, bizType, null);
    }

    @Override
    public List<AttachmentDto> listByBiz(String bizId, BusinessType bizType, String bizAttr) {
        return baseMapper.listByBiz(bizId, (bizType == null ? null : bizType.getType()), bizAttr);
    }

    /**
     * @param fullUpdate 是否先 delete
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void addInfo(String bizId, BusinessType bizType, String bizAttr, AttachmentDto attachment, Boolean fullUpdate) {
        if (fullUpdate) {
            deleteByBiz(bizId, bizType, bizAttr);
        }
        if (attachment == null || StringUtils.isBlank(attachment.getAttachmentId())) {
            return;
        }
        attachmentRelationService.create(attachment.getAttachmentId(),
                (bizId == null ? attachment.getBusinessId() : bizId),
                (bizType == null ? null : bizType.getType()),
                (bizAttr == null ? attachment.getBusinessAttr() : bizAttr));
    }


    /**
     * @param fullUpdate 是否先 delete
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void addInfo(String bizId, BusinessType bizType, String bizAttr, List<AttachmentDto> attachmentList, Boolean fullUpdate) {
        if (fullUpdate) {
            deleteByBiz(bizId, bizType, bizAttr);
        }
        if (CollectionUtil.isEmpty(attachmentList)) {
            return;
        }
        for (AttachmentDto attachment : attachmentList) {
            if (attachment == null || StringUtils.isBlank(attachment.getAttachmentId())) {
                continue;
            }
            attachmentRelationService.create(attachment.getAttachmentId(),
                    (bizId == null ? attachment.getBusinessId() : bizId),
                    (bizType == null ? null : bizType.getType()),
                    (bizAttr == null ? attachment.getBusinessAttr() : bizAttr));
        }
    }

    /**
     * deleteByBiz
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void deleteByBiz(String bizId, BusinessType bizType, String bizAttr) {
        attachmentRelationService.delete(bizId, bizType, bizAttr);
    }

    /**
     * copy
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void copy(String bizId, BusinessType bizType, String bizAttr, String attachmentId) {
        if (StringUtils.isBlank(attachmentId)) {
            return;
        }
        attachmentRelationService.create(attachmentId, bizId, (bizType == null ? null : bizType.getType()), bizAttr);
    }

    /**
     * 根据 ids 获取集合
     */
    @Override
    public List<AttachmentDto> myListByIds(List<String> ids){
        return baseMapper.myListByIds( ids );
    }

}